/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package provider.impl.genomemap.data;

import com.google.common.collect.ImmutableList;
import commons.provider.ProviderException;
import commons.provider.impl.BaseFileBasedProviderImpl;
import commons.util.FreqDist;
import commons.util.Util;
import genomemap.data.AssignmentData;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Susanta Tewari
 */
public class CSVFileBasedAssignmentDataProviderImpl
        extends BaseFileBasedProviderImpl<AssignmentData>
        implements genomemap.provider.Providers.AssignmentDataProviderFileBased {

    /**
     * Method description
     *
     *
     * @param dataFile
     *
     * @return
     *
     * @throws ProviderException
     */
    @Override
    protected AssignmentData createImpl(final File dataFile) throws ProviderException {

        List<String> lines = null;

        try {
            lines = Util.IO.readLines(dataFile);
        } catch (IOException ex) {
            throw new ProviderException("", ex);
        }

        final Map<String, List<String>> map_local = new HashMap<>(lines.size());


        // stores genes processed for a potential use in FreqDist later
        final List<String> input_genes = new ArrayList<>(lines.size());

        for (final String line : lines) {

            final String[] tokens = line.split(",");


            // the first one is gene
            final String gene = tokens[0];

            input_genes.add(gene);


            // the rest are clones
            final Collection<String> clones = new HashSet<>(tokens.length);

            for (int i = 1; i < tokens.length; i++) {
                clones.add(tokens[i]);
            }

            map_local.put(gene, ImmutableList.copyOf(clones));
        }


        // check if there are any duplicate genes defined, if found report it.
        if (lines.size() > map_local.size()) {

            final FreqDist<String> freqDist   = new FreqDist<>(input_genes);
            final Set<String> duplicate_genes = freqDist.withFreqGreaterThan(Integer.valueOf("1"));


            // message for the analysis
            final StringBuilder builder = new StringBuilder(100);

            builder.append("\nDuplicate genes found: " + duplicate_genes
                           + ".\nTheir frequencies: \n");

            for (final String duplicate_gene : duplicate_genes) {
                builder.append(duplicate_gene + ":" + freqDist.getFrequency(duplicate_gene) + "\n");
            }


            // log the analysis
            Logger.getLogger(this.getClass().getName()).log(Level.INFO, builder.toString());


            // log their frequencies
        }

        return new AssignmentData(map_local);
    }
}
